package com.xywy.wjk.widget;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import org.apache.http.entity.mime.MinimalField;

import com.xywy.common.manager.BottomManager;
import com.xywy.wjk.bean.BloodPressureData;
import com.xywy.wjk.bean.WeightData;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Paint.FontMetrics;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.graphics.PathEffect;
import android.graphics.Shader;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

/**
 * 折线图 view
 * 
 * @author wangwenlong
 * 
 */
public class BloodHeartView extends View {
	// 假设的点集
	private int mWidth; // 屏幕宽度
	private float mHeight; // 屏幕高度
	private List<BloodPressureData> gaveWorth; // 外部传进来的值
	private int mode = -1; // 年 月 日 区分 外部传入
	public static final int MODE_WEEK = 1, MODE_DAY = 0, MODE_MOUNTH = 2,
			MODE_YEAR = 3; // 区分年月日
	private List<Float[]> points = new ArrayList<Float[]>(); // 折线图上面的点
	private int mBottomHeight; // 底部线的高度
	private int mTextHeight = 40;

	private float mMaxLineHeight;
	private float mMinLineHeight;
	private int mLeftDistance; // 左边距
	private int mRightDistance; // 右边距

	private Paint valuePaint; // 最大最小值画笔
	private Paint textPain; // 日期画笔
	private Paint grayLinePain; // 灰色线画笔
	private Paint zxLinePaint; // 折线画笔
	private Paint whitePaint; // 白色
	private Paint pathPaint; // path

	private Calendar calendar;

	private String timeStr[] = { "凌晨0点", "6", "中午12点", "18", "24" };

	private String monthStr[] = new String[7];

	private String weekStr[] = new String[7];

	private String yearStr[];
	private float leftText; //左边的文字距离
	private float htemp; // 去掉底部距离的整个高度
	private float distance; // 水平方向的距离
	private int viewWidth; //这个是整个View的宽度 getmesaureWidth();
	private float unitHeight; //这个是单位高度
	private float maxHeight; //最大高度 因为使用的是渐变色  所以如果这边没有设置最大值 他会横向渲染
	private long currentTime; //当前时间 用来确定点
	private Context context;
	private float restHeight ; //剩余的高度  
	
	DecimalFormat df = new DecimalFormat("0");

	public BloodHeartView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		// TODO Auto-generated constructor stub
		mWidth = 200;
		mHeight = 200;
		init();
		this.context = context;
	}

	public BloodHeartView(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
		mWidth = 200;
		mHeight = 200;
		init();
		this.context = context;
	}

	public BloodHeartView(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
		mWidth = 200;
		mHeight = 200;
		init();
		this.context = context;
	}

	// 初始化
	private void init() {
		calendar = Calendar.getInstance();
		// 最大最小值画笔
		valuePaint = new Paint();
		Typeface font = Typeface.create(Typeface.SANS_SERIF, Typeface.NORMAL);
		valuePaint.setTypeface(font);
		valuePaint.setTextSize(40);
		valuePaint.setColor(0xff989696);
		// 底部文字画笔
		textPain = new Paint();
		textPain.setTypeface(font);
		textPain.setTextSize(30);
		textPain.setColor(0xff989696);

		grayLinePain = new Paint(); // 设置画笔
		grayLinePain.setStrokeWidth(2);
		grayLinePain.setColor(0xffdedede);
		grayLinePain.setStyle(Paint.Style.FILL);

		zxLinePaint = new Paint();
		zxLinePaint.setColor(0xfffe8f7d);
		zxLinePaint.setStrokeWidth(5);
		zxLinePaint.setStyle(Style.STROKE);

		whitePaint = new Paint();
		whitePaint.setColor(Color.WHITE);
		whitePaint.setStrokeWidth(2);
		whitePaint.setStyle(Paint.Style.FILL);


		// path 画笔
		pathPaint = new Paint(); // 设置画笔
		pathPaint.setStrokeWidth(3);
		pathPaint.setStyle(Paint.Style.FILL);

	}

	@Override
	protected void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		mBottomHeight = BloodPresureView.dip2px(context, 60);
		if (gaveWorth != null && gaveWorth.size() > 0) {
			//设置左边的点 右边数据文字开始的地方
			initXy("0000", "00");
			points.clear();
			canvas.drawColor(Color.WHITE);
			// 设置点
			initPoint();

			LinearGradient lg = new LinearGradient(0, maxHeight, 0, mHeight
					+ mBottomHeight, 0xfffe8f7d, Color.WHITE,
					Shader.TileMode.MIRROR);
			pathPaint.setShader(lg);
			
			// 画渐变色
			for (int i = 0; i < points.size() - 1; i++) {
				Float point[] = points.get(i);
				Float pointNext[] = points.get(i + 1);
				Path tempPath = new Path();
				tempPath.moveTo(point[0], mHeight + mBottomHeight);
				tempPath.lineTo(point[0], point[1]);
				tempPath.lineTo(pointNext[0], pointNext[1]);
				tempPath.lineTo(pointNext[0], mHeight + mBottomHeight);
				tempPath.close();
				canvas.drawPath(tempPath, pathPaint);
			}

			// 画线 折线
			for (int i = 0; i < (points.size() - 1); i++) {
				Float[] lPoint = points.get(i);
				Float[] rPoint = points.get(i + 1);
				canvas.drawLine(lPoint[0], lPoint[1], rPoint[0], rPoint[1],
						zxLinePaint);
			}

			// 画圆 实心的白色
			for (int i = 0; i < points.size(); i++) {
				Float[] point = points.get(i);
				canvas.drawCircle(point[0], point[1], 8, whitePaint);
			}
			//画圆 空心的橙色
			for (int i = 0; i < points.size(); i++) {
				Float[] point = points.get(i);
				canvas.drawCircle(point[0], point[1], 8, zxLinePaint);
			}

			// 最小值虚线
			String minStr = "" + mMinLineHeight;
			String maxStr = "" + mMaxLineHeight;
			FontMetrics fm = valuePaint.getFontMetrics();
			float textHeight = fm.descent - fm.ascent;
			// 最大值实线
			leftText = valuePaint.measureText(maxStr, 0,maxStr.length());
			if (gaveWorth.size() == 1) {
				minStr = "" + (df.format(mMinLineHeight - 10));
				maxStr = "" + (df.format(mMaxLineHeight + 10));
				if(mMinLineHeight==0)
					minStr = "";
				leftText = valuePaint.measureText(maxStr, 0,maxStr.length());
//				float h = (float) (getMeasuredHeight() - mBottomHeight) / 2;
//				;
//				float addHeight =  (float) (htemp - mHeight - 0.5 * mBottomHeight);
//				float jianHeight =  (float) (htemp  - 0.5 * mBottomHeight);
				float addHeight =  (float) (restHeight);
				float jianHeight =  (float) (2*restHeight);
				
				canvas.drawLine(
						leftText,addHeight, getMeasuredWidth(),  addHeight,
						grayLinePain);
				// 最大值 最小值 标注
				canvas.drawText(maxStr, 0, textHeight / 4 + addHeight,
						valuePaint);

				canvas.drawLine(
						leftText, jianHeight, getMeasuredWidth(), jianHeight,
						grayLinePain);
				// 最大值 最小值 标注
				canvas.drawText(minStr, 0, textHeight / 4 +jianHeight,
						valuePaint);
			} else if (gaveWorth.size() > 1) {
				minStr = "" + (df.format(mMinLineHeight));
				maxStr = "" + (df.format(mMaxLineHeight));
				canvas.drawLine(
						leftText,
						(float) (htemp - (mMaxLineHeight - mMinLineHeight)
								* unitHeight - restHeight), /*0.5 * mBottomHeight*/
						getMeasuredWidth(), (float) (htemp
								- (mMaxLineHeight - mMinLineHeight)
								* unitHeight - restHeight),
						grayLinePain);
				// 最大值 最小值 标注
				canvas.drawText(maxStr, 0,
						(float) (htemp - (mMaxLineHeight - mMinLineHeight)
								* unitHeight - restHeight)
								+ textHeight / 4, valuePaint);

				canvas.drawLine(
						leftText,
						(float) (htemp - restHeight),
						getMeasuredWidth(),
						(float) (htemp - restHeight), grayLinePain);
				// 最大值 最小值 标注
				canvas.drawText(minStr, 0,
						(float) (htemp - restHeight) + textHeight / 4,
						valuePaint);
			}
		} else {
			FontMetrics fm = valuePaint.getFontMetrics();
			float textHeight = fm.descent - fm.ascent;
			canvas.drawText("暂无数据",
					(getMeasuredWidth()) / 2 - valuePaint.measureText("暂无数据")
							/ 2, (getMeasuredHeight() - mBottomHeight) / 2
							+ textHeight / 4, valuePaint);
            initXy("000", "00");
		}

		// 底部时间 和线
		drawBottom(canvas);
	}

	private void initPoint() {
		// TODO Auto-generated method stub
		 maxHeight = mHeight;
		 Calendar currentCalendar = Calendar.getInstance();
			int currentYear = currentCalendar.get(Calendar.YEAR);
			for (int i = 0; i < gaveWorth.size(); i++) {
				if (gaveWorth.get(i) == null)
					continue;
				Float[] point = new Float[2];
				Long l = gaveWorth.get(i).getDate();
				calendar.setTimeInMillis(l);
				int tempYear = calendar.get(Calendar.YEAR);
				long hh = 0;
				switch (mode) {
				case MODE_DAY:
					hh = calendar.get(Calendar.HOUR_OF_DAY);
					break;
				case MODE_MOUNTH:
					if(tempYear == currentYear){
						hh = currentCalendar.get(Calendar.DAY_OF_YEAR) - calendar.get(Calendar.DAY_OF_YEAR);
					}else {
						hh = currentCalendar.get(Calendar.DAY_OF_YEAR) + 31 - calendar.get(Calendar.DATE);
					}
					break;
				case MODE_WEEK:
					if(tempYear == currentYear){
						hh = currentCalendar.get(Calendar.DAY_OF_YEAR) - calendar.get(Calendar.DAY_OF_YEAR);
					}else {
						hh = currentCalendar.get(Calendar.DAY_OF_YEAR) + 31 - calendar.get(Calendar.DATE);
					}
					break;
				case MODE_YEAR:
					Calendar current = Calendar.getInstance();
					int currentM = current.get(current.MONTH);
					int now = calendar.get(current.MONTH);
//					hh = currentM - now;
					if(tempYear == currentYear){
						hh = currentM - now;
					}else {
						hh = 12-now+currentM;
					}
					break;
				default:
					break;
				}
				

			if (mode != MODE_DAY) {
				point[0] = viewWidth - hh * distance - mRightDistance;
			} else {
				point[0] = hh * distance + mLeftDistance;
			}
			float currentHeight = (float) ((gaveWorth.get(i).getHeartRate() - mMinLineHeight)
					* unitHeight * 1.0);
			if (gaveWorth.size() == 1) {
//				point[1] = (float) (getMeasuredHeight() - mBottomHeight) / 2;
//			} else {
//				point[1] = (float) (htemp - currentHeight - 0.5 * mBottomHeight);
//			}
				point[1] = (float) (restHeight*1.5);
			} else {
				point[1] = (float) (htemp - currentHeight - restHeight);
			}
			if (maxHeight > point[1])
				maxHeight = point[1];
			points.add(point);
		}
	}

	public void setGaveWorth(BloodPressureData[] gaveWorth, int mode) {
		this.gaveWorth = new ArrayList<BloodPressureData>();
		for (BloodPressureData temp : gaveWorth)
			if (temp != null)
				this.gaveWorth.add(temp);
		Collections.sort(this.gaveWorth, new weightComp());
		Log.e("this.gaveWorth ", this.gaveWorth.size() + "");
		mMinLineHeight = 400;
		mMaxLineHeight = 0;
		this.mode = mode;
		List<BloodPressureData> temp = new ArrayList<BloodPressureData>();
		if (gaveWorth != null) {
			for (int i = 0; i < gaveWorth.length; i++) {
				if (gaveWorth[i] == null)
					continue;
				temp.add(gaveWorth[i]);
				if (mMaxLineHeight < gaveWorth[i].getHeartRate())
					mMaxLineHeight = gaveWorth[i].getHeartRate();
				if (mMinLineHeight >= gaveWorth[i].getHeartRate())
					mMinLineHeight = gaveWorth[i].getHeartRate();
			}
		}
		for (int i = 0; i < weekStr.length; i++) {
			calendar.setTimeInMillis(System.currentTimeMillis()
					- (1000 * 60 * 60 * 24) * (6 - i));
			if (i == 0) {
				weekStr[i] = (calendar.get(Calendar.MONTH) + 1) + "月"
						+ calendar.get(Calendar.DAY_OF_MONTH) + "";
			} else {
				weekStr[i] = calendar.get(Calendar.DAY_OF_MONTH) + "";
			}
		}
		calendar = Calendar.getInstance();
		for (int i = monthStr.length - 1; i >= 0; i--) {
			if (i == monthStr.length - 1) {
				monthStr[i] = calendar.get(Calendar.DAY_OF_MONTH) + "";
				continue;
			} else if (i == 0) {
				calendar.add(Calendar.DAY_OF_MONTH, -5);
				monthStr[i] = (calendar.get(Calendar.MONTH) + 1) + "月"
						+ calendar.get(Calendar.DAY_OF_MONTH) + "";
			} else {
				calendar.add(Calendar.DAY_OF_MONTH, -5);
				monthStr[i] = calendar.get(Calendar.DAY_OF_MONTH) + "";
			}
		}
		calendar = Calendar.getInstance();
//		int countmonth = calendar.get(Calendar.MONTH);
//		yearStr = new String[countmonth + 1];
//		for (int i = yearStr.length - 1; i >= 0; i--) {
//			if (i == yearStr.length - 1) {
//				yearStr[i] = (calendar.get(Calendar.MONTH) + 1) + "月";
//			} else if (i == 0) {
//				calendar.add(Calendar.MONTH, -1);
//				yearStr[i] = calendar.get(Calendar.YEAR) + "年"
//						+ (calendar.get(Calendar.MONTH) + 1) + "月";
//			} else {
//				calendar.add(Calendar.MONTH, -1);
//				yearStr[i] = (calendar.get(Calendar.MONTH) + 1) + "月";
//			}
//		}
		int countmonth = 6;
		yearStr = new String[countmonth];
		Calendar c = Calendar.getInstance();
		int mouth = c.get(Calendar.MONTH);
		for (int i = 0; i < yearStr.length; i++) {
			if (i == countmonth-1) {
				calendar.add(Calendar.MONTH, -2);
				yearStr[countmonth-i-1] = calendar.get(Calendar.YEAR) + "年"
						+ (calendar.get(Calendar.MONTH)+1) + "月";
			} else if (i==0) {
				yearStr[countmonth-i-1] = (calendar.get(Calendar.MONTH)+1)+"";
			}else {
				calendar.add(Calendar.MONTH, -2);
				yearStr[countmonth-i-1] = (calendar.get(Calendar.MONTH)+1)+"";
			}
		}
		invalidate();
	}

	private void drawBottom(Canvas canvas) {
		System.out.println("年的 ----"+yearStr[0]);
		// 底部线和文字
		canvas.drawLine(leftText, getMeasuredHeight() - mBottomHeight,
				getMeasuredWidth(), getMeasuredHeight() - mBottomHeight,
				grayLinePain);
		switch (mode) {
		case MODE_DAY:
			int height = getMeasuredHeight();
			int distance = mWidth / (timeStr.length - 1);
			for (int i = 0; i < timeStr.length; i++) {
				// calendar.setTimeInMillis(timestmps.get(i));
				// String str = calendar.get(Calendar.HOUR_OF_DAY)+"";
				canvas.drawText(timeStr[i], distance * i + mLeftDistance
						- textPain.measureText(timeStr[i]) / 2, height
						+ mTextHeight - mBottomHeight, textPain);
			}
			break;
		case MODE_WEEK:
			int weekHeight = getMeasuredHeight();
			int weekDistance = mWidth / (weekStr.length - 1);
			for (int i = 0; i < weekStr.length; i++) {
				// calendar.setTimeInMillis(timestmps.get(i));
				// String str = calendar.get(Calendar.HOUR_OF_DAY)+"";
				canvas.drawText(weekStr[i], weekDistance * i + mLeftDistance
						- textPain.measureText(weekStr[i]) / 4, weekHeight
						+ mTextHeight - mBottomHeight, textPain);
			}
			break;
		case MODE_MOUNTH:
			int mounthHeight = getMeasuredHeight();
			int mounthDistance = mWidth / (monthStr.length - 1);
			for (int i = 0; i < monthStr.length; i++) {
				canvas.drawText(monthStr[i], mounthDistance * i + mLeftDistance
						- textPain.measureText(monthStr[i]) / 4, mounthHeight
						+ mTextHeight - mBottomHeight, textPain);
			}
			break;
		case MODE_YEAR:
			int yearHeight = getMeasuredHeight();
			int yearDistance = mWidth / (yearStr.length - 1);
			
//			textPain.setTextSize(18);
			for (int i = 0; i < yearStr.length; i++) {
				if (i == 0) {
					canvas.drawText(yearStr[i], yearDistance * i
							+ mLeftDistance - textPain.measureText(yearStr[i])
							/ 2, yearHeight + mTextHeight - mBottomHeight,
							textPain);
				} else {
					canvas.drawText(yearStr[i], yearDistance * i
							+ mLeftDistance - textPain.measureText(yearStr[i])
							/ 4, yearHeight + mTextHeight - mBottomHeight,
							textPain);
				}
			}
//			textPain.setTextSize(30);
			break;
		default:
			break;
		}
	}

	class weightComp implements Comparator<BloodPressureData> {

		@Override
		public int compare(BloodPressureData f, BloodPressureData s) {
			// TODO Auto-generated method stub
			if (s != null && f != null) {
				long x = f.getDate();
				long y = s.getDate();
				if (x > y) {
					return 1;
				} else {
					return -1;
				}
			} else {
				return 0;
			}
		}

	}

	public int getMode() {
		return mode;
	}
	
	/**
	 * 初始化 高度 左边距 右边距 
	 * @param leftStr
	 * @param rightStr
	 */
	private void initXy(String leftStr,String rightStr){
		mLeftDistance = (int) valuePaint.measureText(leftStr, 0, leftStr.length());
		mRightDistance = (int) textPain.measureText(rightStr, 0, rightStr.length());
		mWidth = getMeasuredWidth() - mLeftDistance - mRightDistance;
		viewWidth = getMeasuredWidth();
		mHeight = (float) (getMeasuredHeight() - 2 * mBottomHeight);
		htemp = (float) (getMeasuredHeight() - mBottomHeight);
		
		restHeight = (getMeasuredHeight() - mBottomHeight)/3;
		
		distance = (float) ((mWidth * 1.0) / 6); // 这个是通过点来平均下来每个点之间
														// 水平距离
		switch (mode) {
		case MODE_DAY:
			distance = (float) ((mWidth * 1.0) / 23);
			break;
		case MODE_MOUNTH:
			distance = (float) ((mWidth * 1.0) / 29);
			break;
		case MODE_WEEK:
			distance = (float) ((mWidth * 1.0) / 6);
			break;
		case MODE_YEAR:
			distance = (float) ((mWidth * 1.0) / 12);
			break;
		default:
			break;
		}
		unitHeight = 0;
		if (mMaxLineHeight == mMinLineHeight) {
			unitHeight = 0;
		} else {
//			unitHeight = (float) (mHeight * 1.0 / (mMaxLineHeight - mMinLineHeight));
			unitHeight = (float) ((htemp-2*restHeight) * 1.0 / (mMaxLineHeight - mMinLineHeight));
		}
	}

}
